package com.wandian.command;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.wandian.admin.AdminCmdMgr;
import com.wandian.texas.GameServer;
import com.wandian.texas.protocol.Protocol;
import com.wandian.util.ClassUtil;
import com.wandian.util.Log;

public final class CommandSet {

	private static final Map<Short, Command> cmdCache = new HashMap<Short, Command>();
	private static final Map<String, AdminCommand> adminCmdCache = new HashMap<String, AdminCommand>();
	private static final Map<Short, String> cmdSocket = new HashMap<Short, String>();

	public static boolean load() {
		try {
			Package pack = GameServer.class.getPackage();
			Set allClasses = ClassUtil.getClasses(pack);
			StringBuilder sb = new StringBuilder("[");
			for (Object clazz : allClasses) {
				try {
					Cmd cmd = (Cmd) ((Class) clazz).getAnnotation(Cmd.class);
					if (cmd != null) {
						if (cmdCache.get(cmd.code()) != null) {
							String name = cmdCache.get(Short.valueOf(cmd.code())).getClass().getName();
							Log.error("cmd code error, code : " + cmd.code() + " exist :" + name + ", new : " + ((Class) clazz).getName());
							return false;
						}
						cmdCache.put(cmd.code(), (Command) ((Class) clazz).newInstance());
						sb.append("init cmd  " + cmd.code() + " ,class name:" + clazz.toString() + System.getProperty("line.separator"));
					} else {
						AdminCmd adminCmd = (AdminCmd) ((Class) clazz).getAnnotation(AdminCmd.class);
						if (adminCmd != null) {
							if (adminCmdCache.get(adminCmd.code()) != null) {
								String name = adminCmdCache.get(adminCmd.code()).getClass().getName();
								Log.error("cmd code error, code : " + adminCmd.code() + " exist :" + name + ", new : " + ((Class) clazz).getName());
								return false;
							}
							adminCmdCache.put(adminCmd.code(), (AdminCommand) ((Class) clazz).newInstance());
						}
					}
				} catch (Exception e) {
					Log.error("load command fail, command name : " + ((Class) clazz).getName(), e);
					e.printStackTrace();
				}
			}
			pack = AdminCmdMgr.class.getPackage();
			allClasses = ClassUtil.getClasses(pack);
			for (Object clazz : allClasses) {
				try {
					Cmd cmd = (Cmd) ((Class) clazz).getAnnotation(Cmd.class);
					if (cmd != null) {
						if (cmdCache.get(cmd.code()) != null) {
							String name = cmdCache.get(Short.valueOf(cmd.code())).getClass().getName();
							Log.error("cmd code error, code : " + cmd.code() + " exist :" + name + ", new : " + ((Class) clazz).getName());
							return false;
						}
						cmdCache.put(cmd.code(), (Command) ((Class) clazz).newInstance());
						sb.append("init cmd  " + cmd.code() + " ,class name:" + clazz.toString() + System.getProperty("line.separator"));
					} else {
						AdminCmd adminCmd = (AdminCmd) ((Class) clazz).getAnnotation(AdminCmd.class);
						if (adminCmd != null) {
							if (adminCmdCache.get(adminCmd.code()) != null) {
								String name = adminCmdCache.get(adminCmd.code()).getClass().getName();
								Log.error("cmd code error, code : " + adminCmd.code() + " exist :" + name + ", new : " + ((Class) clazz).getName());
								return false;
							}
							adminCmdCache.put(adminCmd.code(), (AdminCommand) ((Class) clazz).newInstance());
						}
					}
				} catch (Exception e) {
					Log.error("load command fail, command name : " + ((Class) clazz).getName(), e);
					e.printStackTrace();
				}
			}
			sb.append("cmdCache size : " + cmdCache.size() + System.getProperty("line.separator") + "adminCmdCache size : " + adminCmdCache.size() + "]");
			Log.info(sb.toString());
			cmdSocket.put((short) 3998, "LobbyCmd");
			cmdSocket.put(Protocol.CMD_CHANGE_SEATICO, "CMD_CHANGE_SEATICO");
			cmdSocket.put((short) 3999, "GameRoomCmd");
			cmdSocket.put((short) 4000, "EnterRoomCmd");
			cmdSocket.put((short) 4001, "RoomInfoCmd");
			cmdSocket.put((short) 4002, "SitdownCmd");
			cmdSocket.put((short) 4003, "InGAameRoomCmd");
			cmdSocket.put((short) 4004, "OutGameRoomCmd");
			cmdSocket.put((short) 4005, "StandUpCmd");
			cmdSocket.put((short) 4006, "StartGameCmd");
			cmdSocket.put((short) 4007, "CMD_GameMessageList");
			cmdSocket.put((short) 4008, "CMD_SETROOMINFO");
			cmdSocket.put((short) 4009, "CMD_PLAYERS");

			cmdSocket.put((short) 4010, "CMD_REQUESTINFOMATION");
			cmdSocket.put((short) 4011, "CMD_ROOMINFOUPDATE");
			cmdSocket.put((short) 4012, "CMD_ROOMPLAYERNUMCHANGE");
			cmdSocket.put((short) 4013, "CMD_OPERATION_NEXT");
			cmdSocket.put((short) 4014, "CMD_OPERATION_REQUEST");
			cmdSocket.put((short) 4015, "CMD_OPERATION_SUCC");
			cmdSocket.put((short) 4016, "CMD_CUR_POT");
			cmdSocket.put((short) 4017, "CMD_POTS");
			cmdSocket.put((short) 4018, "CMD_SNAPCARDS_FLOP");
			cmdSocket.put((short) 4019, "CMD_SNAPCARDS_TURN");
			cmdSocket.put((short) 4020, "CMD_SNAPCARDS_RIVER");
			cmdSocket.put((short) 4021, "CMD_SHOW");

			cmdSocket.put((short) 5000, "CMD_GAME_OVER");
			cmdSocket.put((short) 5001, "CMD_UPDATE_CORNUCOPIA");
			cmdSocket.put((short) 5002, "CMD_REWARD_CORNUCOPIA");
			cmdSocket.put((short) 5003, "CMD_TODAYCORNUCOPIALIST");
			cmdSocket.put((short) 5004, "CMD_MYCORNUCOPIALIST");
			cmdSocket.put((short) 10003, "CMD_GAME_ROOM_SOCKET_CLOSE");
			return true;
		} catch (Exception e) {
			Log.error("命令管理器解析错误", e);
		}
		return false;
	}

	public static Command getCommand(short code) {
		return cmdCache.get(code);
	}

	public static String getCmdName(short code) {
		Command cmd = cmdCache.get(code);
		if (cmd != null) {
			return cmd.getClass().getName().substring(cmd.getClass().getName().lastIndexOf("."));
		}
		return cmdSocket.get(code);
	}

	public static AdminCommand getCommand(String code) {
		return adminCmdCache.get(code);
	}

	public static Map<String, AdminCommand> getAllAdminCommand() {
		return adminCmdCache;
	}
}
